package id.co.rho.scoring.cid.client.mvc.compare;

import id.co.rho.scoring.cid.client.helper.Resources;
import id.co.rho.scoring.cid.client.mvc.AppView;
import id.co.rho.scoring.cid.client.utils.CommonUtils;
import id.co.rho.scoring.cid.client.utils.Folder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.Orientation;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelIconProvider;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.PagingModelMemoryProxy;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayoutData;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.extjs.gxt.ui.client.widget.treegrid.EditorTreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGridCellRenderer;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGridSelectionModel;
import com.google.gwt.user.client.ui.AbstractImagePrototype;

public class CompareModelUIWeb implements CompareModelUI {

	private FormLayout formlayout;
	private ComboBox<ModelData> combo1;
	private ComboBox<ModelData> combo2;
	private TextField<String> txtModel1;
	private TextField<String> txtModel2;
	private ListStore<ModelData> models = new ListStore<ModelData>();
	private FieldSet fsSearch;
	private Button compareButton;
	private FormPanel formPanel;
	private VBoxLayoutData vbData1;
	private VBoxLayoutData vbData2;
	private ContentPanel content;
	private VBoxLayout vBoxLayout;
	private ContentPanel centerPanel;
	private ContentPanel treePanel;
	private Folder model1;
	private TreeStore<ModelData> store1;
	private Folder model2;
	private TreeStore<ModelData> store2;
	private ColumnConfig criteriaName, criteriaNumber, criteriaRank,criteriaWeight,criteriaType,id,parentId;
	private ColumnModel cm;
	private TreeGrid<ModelData> tree1;
	private TreeGrid<ModelData> tree2;
	private PagingModelMemoryProxy proxy;
	private PagingLoader<PagingLoadResult<ModelData>> loader;
	private ListStore<ModelData> listStore;
	private PagingToolBar toolBar;
	private List<ColumnConfig> configs;
	private ColumnModel columnModel;
	private Grid<ModelData> grid;
	private Long modelId1;
	private Long modelId2;
	private Integer filterId;
	
	private Window window;

	@Override
	public void initialize() {
		vbData1 = new VBoxLayoutData();
		vbData1.setFlex(0);
		vbData2 = new VBoxLayoutData();
        vbData2.setFlex(1);
		vBoxLayout = new VBoxLayout(VBoxLayout.VBoxLayoutAlign.STRETCH);
		
		treePanel = new ContentPanel();  
		treePanel.setHeading("RowLayout: Orientation set to horizontal");  
		treePanel.setLayout(new RowLayout(Orientation.HORIZONTAL));  
		treePanel.setSize(400, 300);  
		treePanel.setFrame(true);  
		treePanel.setCollapsible(true);  
		
	    model1 = new Folder();
		store1 = new TreeStore<ModelData>();
		store1.add(model1.getChildren(), true);
		
		model2 = new Folder();
		store2 = new TreeStore<ModelData>();
		store2.add(model2.getChildren(), true);
		
		TreeGridCellRenderer<ModelData> labelColumnRenderer = new TreeGridCellRenderer<ModelData>() {
            @Override
            public Object render(ModelData modelData, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ModelData> modelDataListStore, Grid<ModelData> modelDataGrid) {

                Object result = super.render(modelData, property, config, rowIndex, colIndex, modelDataListStore, modelDataGrid);
                config.style = config.style.replaceAll("background-color:[#1-9a-zA-Z]+;", "");
                if (!CommonUtils.isEmpty(modelData.<String>get("diff"))) {
                	if (modelData.<String>get("diff").equalsIgnoreCase("true")) {
                        config.style = config.style + "background-color:#FF33CC;";
                	} else if (modelData.<String>get("diff").equalsIgnoreCase("new")) {
                        config.style = config.style + "background-color:#FFF333;";
                	}
                }
                
                return result;
            }
        };
		
        
		
		criteriaName = new ColumnConfig("criteriaName", "Name", 100);
		criteriaName.setRenderer(labelColumnRenderer);
		criteriaNumber = new ColumnConfig("criteriaNumber", "Number", 100);
		criteriaRank = new ColumnConfig("criteriaRank", "Rank", 100);
		criteriaWeight = new ColumnConfig("criteriaWeight", "Weight", 100);
		criteriaType = new ColumnConfig("criteriaType", "Type", 100);
		criteriaName.setSortable(false);
		criteriaNumber.setSortable(false);
		criteriaRank.setSortable(false);
		criteriaType.setSortable(false);
		criteriaWeight.setSortable(false);
		
		id = new ColumnConfig("id", "Id", 100);
		parentId = new ColumnConfig("parentId", "Parent", 100);
		parentId.setHidden(true);
		id.setHidden(true);
		cm = new ColumnModel(Arrays.asList(criteriaName, criteriaNumber, criteriaRank,criteriaWeight,criteriaType,id,parentId));
		
		tree1 = new EditorTreeGrid<ModelData>(store1, cm);
		tree1.setBorders(true);
		tree1.setSize(400, 400);
		tree1.setAutoExpandColumn("criteriaName");
		tree1.setTrackMouseOver(false);
		tree1.setSelectionModel(new TreeGridSelectionModel<ModelData>());
		tree1.expandAll();
		tree1.setIconProvider(new ModelIconProvider<ModelData>() {
			@Override
			public AbstractImagePrototype getIcon(final ModelData model) {
				AbstractImagePrototype result = Resources.ICONS.textCriteria();
				if (!CommonUtils.isEmpty(model.<String> get("criteriaType"))) {
					if (model.<String> get("criteriaType").equalsIgnoreCase(
							"answer")) {
						result = Resources.ICONS.answer();
					} else if (model.<String> get("criteriaType")
							.equalsIgnoreCase("question")) {
						result = Resources.ICONS.question();
					}
				}

				return result;
			}
		});
		
		tree2 = new EditorTreeGrid<ModelData>(store2, cm);
		tree2.setBorders(true);
		tree2.setSize(400, 400);
		tree2.setAutoExpandColumn("criteriaName");
		tree2.setTrackMouseOver(false);
		tree2.setSelectionModel(new TreeGridSelectionModel<ModelData>());
		tree2.expandAll();
		tree2.setIconProvider(new ModelIconProvider<ModelData>() {
			@Override
			public AbstractImagePrototype getIcon(final ModelData model) {
				AbstractImagePrototype result = Resources.ICONS.textCriteria();
				if (!CommonUtils.isEmpty(model.<String> get("criteriaType"))) {
					if (model.<String> get("criteriaType").equalsIgnoreCase(
							"answer")) {
						result = Resources.ICONS.answer();
					} else if (model.<String> get("criteriaType")
							.equalsIgnoreCase("question")) {
						result = Resources.ICONS.question();
					}
				}

				return result;
			}
		});

	    treePanel.add(tree1,new RowData(0.5, 1, new Margins(4)));  
	    treePanel.add(tree2,new RowData(0.5, 1, new Margins(4)));  
	    treePanel.setScrollMode(Style.Scroll.AUTO);
	    
		formlayout = new FormLayout();
		formlayout.setLabelAlign(FormPanel.LabelAlign.LEFT);

		fsSearch = new FieldSet();
		fsSearch.setHeading("Compare Model");
		fsSearch.setLayout(formlayout);

		combo1 = new ComboBox<ModelData>();
		combo1.setEmptyText("Select a model ...");
		combo1.setDisplayField("name");
		combo1.setValueField("id");
		combo1.setWidth(150);
		combo1.setStore(this.models);
		combo1.setTriggerAction(TriggerAction.ALL);
		combo1.setName("model1");
		combo1.setFieldLabel("Model 1");
		combo1.setAllowBlank(false);

		combo2 = new ComboBox<ModelData>();
		combo2.setEmptyText("Select a model ...");
		combo2.setDisplayField("name");
		combo2.setValueField("id");
		combo2.setWidth(150);
		combo2.setStore(this.models);
		combo2.setTriggerAction(TriggerAction.ALL);
		combo2.setName("model2");
		combo2.setFieldLabel("Model 2");
		combo2.setAllowBlank(false);
		
		txtModel1 = new TextField<String>();
		txtModel1.setFieldLabel("Model 1");
		txtModel1.setReadOnly(true);
		
		txtModel2 = new TextField<String>();
		txtModel2.setFieldLabel("Model 2");
		txtModel2.setReadOnly(true);
		txtModel1.addListener(Events.OnClick, new Listener<BaseEvent>() {

			@Override
			public void handleEvent(BaseEvent be) {
				filterId = 1;
				window.show();
			}
		});

		txtModel2.addListener(Events.OnClick, new Listener<BaseEvent>() {

			@Override
			public void handleEvent(BaseEvent be) {
				filterId = 2;
				window.show();
			}
		});

//		fsSearch.add(combo1);
//		fsSearch.add(combo2);
		fsSearch.add(txtModel1);
		fsSearch.add(txtModel2);

		LayoutContainer lcButton = new LayoutContainer();
		lcButton.setStyleAttribute("margin-top", "10px");
		lcButton.setLayout(new HBoxLayout());
		fsSearch.add(lcButton);

		compareButton = new Button();
		compareButton.setStyleAttribute("padding-left", "5px");
		compareButton.setText("Compare");
		lcButton.add(compareButton);

		formPanel = new FormPanel();
		formPanel.setHeading("Compare Model");
		formPanel.setScrollMode(Style.Scroll.AUTO);
		formPanel.add(fsSearch);

		content = new ContentPanel();
		content.setLayout(vBoxLayout);
		
		content.add(formPanel, vbData1);
		content.setScrollMode(Style.Scroll.AUTO);
		content.add(treePanel, vbData2);
		content.layout();
		content.setHeaderVisible(false);
		initWindow();

	}
	
	public void initWindow() {
		window = new Window();
		window.setSize(500, 350);
		window.setPlain(true);
		window.setModal(true);
		window.setBlinkModal(true);
		window.setHeading("Scoring Model");
		window.setLayout(new FitLayout());
		
		proxy = new PagingModelMemoryProxy(this.models.getModels());  
	    loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy);  
	    loader.setRemoteSort(true);  
	    
	    listStore = new ListStore<ModelData>(loader);

	    toolBar = new PagingToolBar(10);  
	    toolBar.bind(loader);  
	    loader.load(0, 10);
		configs = new ArrayList<ColumnConfig>();

		configs.add(new ColumnConfig("id","",0));
		configs.add(new ColumnConfig("name", "Name", 200));
		configs.add(new ColumnConfig("type", "Type", 200));
		configs.add(new ColumnConfig("revision", "Revision", 100));
		columnModel = new ColumnModel(configs);
		columnModel.getColumn(0).setHidden(true);
	    grid = new Grid<ModelData>(listStore, columnModel);
        grid.setBorders(true);  
        grid.setAutoExpandColumn("name");  
        grid.getAriaSupport().setDescribedBy(toolBar.getId() + "-display");  

        window.setFrame(true);
        window.setHeading("Scoring Model List");
        window.setButtonAlign(HorizontalAlignment.CENTER);
        window.setBottomComponent(toolBar);
        window.add(grid);
        window.add(grid);	
		grid.addListener(Events.CellDoubleClick, new Listener<BaseEvent>() {

			@Override
			public void handleEvent(BaseEvent be) {
				GridEvent ge = (GridEvent) be;
				if(filterId==1){
					modelId1 = Long.valueOf(ge.getModel().get("id").toString());
					txtModel1.setValue(grid.getSelectionModel().getSelectedItem().get("name").toString());
					window.hide();
				}else if(filterId==2){
					modelId2 = Long.valueOf(grid.getSelectionModel().getSelectedItem().get("id").toString());
					txtModel2.setValue(grid.getSelectionModel().getSelectedItem().get("name").toString());
					window.hide();
				}
			}
		});

	}

	@Override
	public void show() {
		centerPanel = (ContentPanel) Registry.get(AppView.CENTER_PANEL);
		centerPanel.removeAll();
		centerPanel.setLayout(new FitLayout());
		centerPanel.add(content);
		centerPanel.layout();
		modelId1 = null;
		modelId2 = null;
	}

	@Override
	public void setModels(ListStore<ModelData> models) {
		this.models = models;

		combo1.clear();
		combo1.setStore(this.models);
		combo1.recalculate();

		combo2.clear();
		combo2.setStore(this.models);
		combo2.recalculate();

		vBoxLayout.layout();
		content.layout();
		centerPanel.layout();
		
		this.models = models;
		proxy.setData(models.getModels());
		listStore.getLoader().load();
		grid.getView().refresh(true);
		window.layout();
	}
	
	@Override
	public void setModel(Folder model1, Folder model2) {
		this.model1 = model1;
		this.tree1.expandAll();
		store1.removeAll();
		store1.add(model1.getChildren(), true);
		tree1.expandAll();
		
		this.model2 = model2;
		this.tree2.expandAll();
		store2.removeAll();
		store2.add(model2.getChildren(), true);
		tree2.expandAll();
		
		treePanel.layout();
		vBoxLayout.layout();
		content.layout();
		centerPanel.layout();
		

	}
	
	@Override
	public void clearData() {
		store1.removeAll();
		store2.removeAll();
		formPanel.reset();
		treePanel.layout();
		vBoxLayout.layout();
		content.layout();
		centerPanel.layout();
	}
	
	@Override
	public Button getCompareButton() {
		return compareButton;
	}

	@Override
	public ComboBox<ModelData> getCombo1() {
		return combo1;
	}
	
	@Override
	public ComboBox<ModelData> getCombo2() {
		return combo2;
	}
	
	@Override
	public Long getModelId1() {
		return modelId1;
	}

	@Override
	public Long getModelId2() {
		return modelId2;
	}

	@Override
	public Grid<ModelData> getGrid() {
		return grid;
	}
	
	
	
	
}
